//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//	wbndis51.c
//		
//	history :
//
//	Description:
//		Implement the incremental OIDs in NIDS5.1
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include "os_common.h"

/*-------------------- Local function definition ---------------------------*/
void drv_translate_bss_ex( IN PWB32_ADAPTER Adapter, NDIS_WLAN_BSSID_EX *pndis_bss, bss_desc_tt *pbss );
void NetworkTypeConvert(PNDIS_802_11_NETWORK_TYPE pNetworkType, UCHAR band);
void ChannelNumToFreq(UCHAR NetworkType, UCHAR ChannelNumber, ULONG *freq);
UCHAR* get_name_of_region(WLAN_REGION_CODE region);
//ULONG* get_channels_of_region(WLAN_REGION_CODE region);
USHORT ChanNo2String(UCHAR ChNo, UCHAR * Str);

// 20040114.3 Add
VOID WbNdis51_initial( IN PWB32_ADAPTER Adapter )
{
	PNDIS51_DESIRED_PARAMETER pN51 = &Adapter->DesiredNdis51Parameter;

	NdisMInitializeTimer( &pN51->scan_sync_timer,
						  Adapter->WbNdis.MiniportAdapterHandle,
                          WbNdis51_oid_sync,
                          Adapter);

	NdisMInitializeTimer( &pN51->Connect_timer,
						  Adapter->WbNdis.MiniportAdapterHandle,
                          WbNdis51_connect,
                          Adapter);

	// Modify to 2sec due to First disconnect event will be indicated
	NdisMSetTimer( &pN51->scan_sync_timer, 2000 );

	if( !psSCAN->BScanEnable )
		NdisMSetTimer( &pN51->Connect_timer, 1000 );
}
VOID WbNdis51_destroy( IN PWB32_ADAPTER Adapter )
{
	PNDIS51_DESIRED_PARAMETER pN51 = &Adapter->DesiredNdis51Parameter;
	BOOLEAN	cancel;

	NdisMCancelTimer( &pN51->scan_sync_timer, &cancel );
	if( !psSCAN->BScanEnable ) NdisMCancelTimer( &pN51->Connect_timer, &cancel );
}
VOID WbNdis51_connect( IN PVOID s1, IN PWB32_ADAPTER Adapter, IN PVOID s3, IN PVOID s4 )
{
	PNDIS51_DESIRED_PARAMETER pN51 = &Adapter->DesiredNdis51Parameter;

	if( pN51->ConnectCount )
	{
		if( CURRENT_LINK_ON )
		{
			pN51->ConnectCount = 0;
			pN51->ConnectInterval = 0;
		}
		else
		{
			pN51->ConnectInterval--;
			if( pN51->ConnectInterval <= 0 )
			{
				sme_set_desired_ssid( Adapter, pN51->CurrentSSID, (UCHAR)pN51->CurrentSSIDLength );
				pN51->ConnectCount = 0;
			}
		}
	}

	NdisMSetTimer( &pN51->Connect_timer, 1000 );
}

VOID WbNdis51_oid_sync( IN PVOID s1, IN PWB32_ADAPTER Adapter, IN PVOID s3, IN PVOID s4 )
{
	PNDIS51_DESIRED_PARAMETER pN51 = &Adapter->DesiredNdis51Parameter;

	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("BG scan sec = %d\n", pN51->sync_count ));
	#endif

	//Periodically query the h/w radio status
	CheckHwRadioStatus( Adapter );

	if( pN51->sync_scan_require )
	{
		if (((UINT)Adapter->WbNdis.connect_status != (UINT)NDIS_STATUS_MEDIA_CONNECT) ||
			(Adapter->Mds.TxToggle == FALSE))
		{
			if ((pN51->sync_count >= 60) || (pN51->sync_count <= 66))
				psSCAN->ScanTimeStamp++;//background scan
			#ifdef _PE_STATE_DUMP_
			WBDEBUG(("Issue scanning\n"));
			#endif
			sme_set_bssid_list_scan(Adapter,NULL);
            //to update pmkid table in OS
            #ifdef _WPA2_
            if(psSME->wpa_ok && psSME->bDesiredAuthMode==WPA2PSK_AUTH)
               OS_PMKID_STATUS_EVENT( Adapter );
            #endif //end def _WPA2_
		}

		pN51->sync_count = 0;

		pN51->sync_scan_require = 0;
	}

	pN51->sync_count += 2;

	//FUNK software won't issue scanning per 60 sec.
	if( !TS_RUNNING_IN_TESTSTA_MODE )
	{
		if( (pN51->sync_count == 66) && psSCAN->BScanEnable )
			pN51->sync_scan_require = 1;//Enfore to issue background scanning
	}

	Adapter->Mds.TxToggle = FALSE;	//move from roamtask.c to clear.
									//2 seconds later it will be true if there is any tx activity.
									//If it is still false, the scan is permitted. [20050706]

	NdisMSetTimer( &pN51->scan_sync_timer, 2000 );
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
NDIS_STATUS Ndis51QueryInformation( IN PWB32_ADAPTER pcore_data,
                                    IN NDIS_OID Oid,
                                    IN PVOID InformationBuffer,
                                    IN ULONG InformationBufferLength,
                                    OUT PULONG  pMoveBytes)
{
    UCHAR  count,j;
    NDIS_STATUS ret = NDIS_STATUS_SUCCESS;
    UINT        bytes_needed;
	PWB32_ADAPTER Adapter = pcore_data;

	#ifdef _PE_OID_DUMP_
	DbgPrintfOID51(Oid, TRUE);
	#endif
    switch(Oid)
    {
	/* The follow OID must be supported ++++++++++++++++++++++++++++++++++++*/

	case OID_GEN_PHYSICAL_MEDIUM:

		bytes_needed = sizeof(NDIS_PHYSICAL_MEDIUM);

		if(bytes_needed <= InformationBufferLength)
		{
			PNDIS_PHYSICAL_MEDIUM	pPhysMedia = (PNDIS_PHYSICAL_MEDIUM)InformationBuffer;
			*pPhysMedia = NdisPhysicalMediumWirelessLan;
		}
		break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_BSSID:

        bytes_needed = 6;

        if(bytes_needed <= InformationBufferLength)
        {
            if (sme_get_bssid(pcore_data, InformationBuffer) < 0)
            {
                ret = NDIS_STATUS_ADAPTER_NOT_READY;
            }
        }
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_SSID:

        bytes_needed = sizeof(NDIS_802_11_SSID);

        if (bytes_needed <= InformationBufferLength)
        {
            PNDIS_802_11_SSID   p;

            p = (PNDIS_802_11_SSID) InformationBuffer;

			p->SsidLength = 0;
			sme_get_ssid(pcore_data, p->Ssid, (UCHAR *)&(p->SsidLength));
			#ifdef _PE_OID_DUMP_
			{
				UCHAR ssid[50];

			OS_MEMORY_COPY(ssid, (UCHAR *)p->Ssid, (UCHAR)p->SsidLength);
			ssid[p->SsidLength] = '\0';
			WBDEBUG(("GET ssid=%s\n", ssid));
			}
			#endif
        }
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_NETWORK_TYPES_SUPPORTED:

        bytes_needed = sizeof(NDIS_802_11_NETWORK_TYPE_LIST);
		switch (psLOCAL->bMacOperationMode)
		{
			case MODE_802_11_A:
			case MODE_802_11_B:
				break;
			case MODE_802_11_ABG:
				bytes_needed += (sizeof(NDIS_802_11_NETWORK_TYPE)*2);
				break;
			default:
				bytes_needed += sizeof(NDIS_802_11_NETWORK_TYPE);
				break;
		}
        if(bytes_needed <= InformationBufferLength)
        {
            PNDIS_802_11_NETWORK_TYPE_LIST  p;
			UINT	tmpp = 0;

			tmpp = sizeof(NDIS_802_11_NETWORK_TYPE);
            p = (PNDIS_802_11_NETWORK_TYPE_LIST) InformationBuffer;
			if (psLOCAL->bMacOperationMode == MODE_802_11_A)
			{
				p->NumberOfItems    = 1;
				p->NetworkType[0]   = Ndis802_11OFDM5;
			}
			else if (psLOCAL->bMacOperationMode == MODE_802_11_ABG)
			{
				p->NumberOfItems    = 3;
				p->NetworkType[0]   = Ndis802_11DS;
				p->NetworkType[1]   = Ndis802_11OFDM5;
				p->NetworkType[2]	= Ndis802_11OFDM24;
			}
			else if (psLOCAL->bMacOperationMode == MODE_802_11_B)
			{
				p->NumberOfItems    = 1;
				p->NetworkType[0]   = Ndis802_11DS;
			}
			else
			{
				p->NumberOfItems    = 2;
				p->NetworkType[0]   = Ndis802_11DS;
				p->NetworkType[1]   = Ndis802_11OFDM24;
			}
        }
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_NETWORK_TYPE_IN_USE:

		bytes_needed = sizeof(NDIS_802_11_NETWORK_TYPE);

		if(bytes_needed <= InformationBufferLength)
        {
            PNDIS_802_11_NETWORK_TYPE   p;
			UCHAR						BandType;

            p = (PNDIS_802_11_NETWORK_TYPE) InformationBuffer;

			sme_get_network_type_in_use(pcore_data, &BandType);
			NetworkTypeConvert(p, BandType);
		}
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_RSSI:

        bytes_needed = sizeof(NDIS_802_11_RSSI);

        if(bytes_needed <= InformationBufferLength)
        {
            NDIS_802_11_RSSI    *p;

            p = (NDIS_802_11_RSSI *) InformationBuffer;
            sme_get_rssi(pcore_data, p);
        }
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_INFRASTRUCTURE_MODE:

        bytes_needed = sizeof(NDIS_802_11_NETWORK_INFRASTRUCTURE);

        if(bytes_needed <= InformationBufferLength)
        {
            PNDIS_802_11_NETWORK_INFRASTRUCTURE p;
            UCHAR  bss_type;

            p = (PNDIS_802_11_NETWORK_INFRASTRUCTURE) InformationBuffer;

			*p = Ndis802_11AutoUnknown;// Default value setting
            if (sme_get_bss_type(pcore_data, &bss_type) != -1)
            {
				if(bss_type == ESS_NET)
	                *p = Ndis802_11Infrastructure;
                else if(bss_type == IBSS_NET)
	                *p = Ndis802_11IBSS;
			}
        }
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_FRAGMENTATION_THRESHOLD:

        bytes_needed = sizeof(NDIS_802_11_FRAGMENTATION_THRESHOLD);

        if(bytes_needed <= InformationBufferLength)
        {
            NDIS_802_11_FRAGMENTATION_THRESHOLD *p;

            p = (NDIS_802_11_FRAGMENTATION_THRESHOLD *) InformationBuffer;
            sme_get_fragment_threshold(pcore_data, p);
        }
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_RTS_THRESHOLD:

        bytes_needed = sizeof(NDIS_802_11_RTS_THRESHOLD);

        if(bytes_needed <= InformationBufferLength)
        {
            NDIS_802_11_RTS_THRESHOLD   *p;

            p = (NDIS_802_11_RTS_THRESHOLD *) InformationBuffer;
            sme_get_rts_threshold(pcore_data, p);
        }
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_SUPPORTED_RATES:

        bytes_needed = 8;

        if(bytes_needed <= InformationBufferLength)
        {
            PUCHAR  p;

            //The size of NDIS_802_11_RATES is 8 bytes
            p = (PUCHAR) InformationBuffer;
            p[0] = 0x82;    // Basic and operating rate for   1Mbps
            p[1] = 0x84;    // Basic and operating rate for   2Mbps
            p[2] = 0x8b;    // Basic and operating rate for 5.5Mbps
            p[3] = 0x96;    // Basic and operating rate for  11Mbps
            p[4] = 0x00;    // End
        }
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_CONFIGURATION:

        bytes_needed = sizeof(NDIS_802_11_CONFIGURATION);

        if(bytes_needed <= InformationBufferLength)
        {
            PNDIS_802_11_CONFIGURATION  p;
            UCHAR  current_channel, current_band;
			NDIS_802_11_NETWORK_TYPE	NetworkType;
			ULONG channel_freq = 0;

            p = (PNDIS_802_11_CONFIGURATION) InformationBuffer;
            p->Length = sizeof(NDIS_802_11_CONFIGURATION);
			// PD43 20030530
			p->BeaconPeriod = 0;
            sme_get_beacon_period(pcore_data, (USHORT *)&(p->BeaconPeriod));
			// PD43 20030530
			p->ATIMWindow = 0;
            sme_get_atim_window(pcore_data, (USHORT *)&(p->ATIMWindow));
            sme_get_current_channel(pcore_data, &current_channel);
			sme_get_current_band(pcore_data, &current_band);
			NetworkTypeConvert(&NetworkType, current_band);
			ChannelNumToFreq( (UCHAR)NetworkType, current_channel, &channel_freq);
			p->DSConfig = channel_freq * 1000;

            p->FHConfig.Length      = sizeof(NDIS_802_11_CONFIGURATION_FH);
            p->FHConfig.HopPattern  = 0;
            p->FHConfig.HopSet      = 0;
            p->FHConfig.DwellTime   = 0;
        }
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_BSSID_LIST:

		sme_get_scan_bss_count(pcore_data, &count);
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("[DRV] ** bss_count = %d\n", count));
		#endif
		//
		bytes_needed = sizeof(ULONG);

		{
			UCHAR	boMsRadioOff;
			RadioOff		RadioOffData;

			// 1: off, 0: on
			sme_get_radio_mode(Adapter, &RadioOffData);
			sme_get_ms_radio_mode(Adapter, &boMsRadioOff);
			if (boMsRadioOff || RadioOffData.boHwRadioOff || RadioOffData.boSwRadioOff)
			{
				count = 0;
				bytes_needed += sizeof(NDIS_WLAN_BSSID_EX);
			}
		}

        for (j=0; j < count; j++)
        {
			bss_desc_tt		*pbss;

        	bytes_needed += (sizeof(NDIS_WLAN_BSSID_EX)-4);
            sme_get_scan_bss(pcore_data, j, &pbss);
			Assemble_IE(pcore_data, pbss->wIndex);

			// 20061108 Add for WPS
			bytes_needed += pbss->WPS_IE_length;

            bytes_needed += ((pbss->ies_len + 3) & ~0x03);
        }
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("InformationBufferLength =%d\n", InformationBufferLength));
		WBDEBUG(("bytes_needed =%d\n", bytes_needed));
		#endif
		//------------------
        if(bytes_needed <= InformationBufferLength)
        {
            NDIS_802_11_BSSID_LIST_EX   *p;
            NDIS_WLAN_BSSID_EX          *pndis_bss;

            UCHAR                      i;
            bss_desc_tt              *pscan_bss = NULL; // important!!!

            NdisZeroMemory(InformationBuffer, bytes_needed);
            p = (NDIS_802_11_BSSID_LIST_EX *)InformationBuffer;


            // get and translate all the BSSs found during the scan
            pndis_bss = (NDIS_WLAN_BSSID_EX*) &(p->Bssid[0]);

            for (i=0; i < count; i++)
            {
                sme_get_scan_bss(pcore_data, i, &pscan_bss);
                drv_translate_bss_ex( Adapter, pndis_bss, pscan_bss );

                pndis_bss = (NDIS_WLAN_BSSID_EX*) ((UCHAR*)pndis_bss + pndis_bss->Length);
            }
            p->NumberOfItems = i;
        }
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("***** OID_802_11_BSSID_LIST return value =%x\n", ret));
		#endif
		//------------------------------------------
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_AUTHENTICATION_MODE:
        bytes_needed = sizeof(NDIS_802_11_AUTHENTICATION_MODE);
        if(bytes_needed <= InformationBufferLength)
        {
            PNDIS_802_11_AUTHENTICATION_MODE    p;
            UCHAR auth_mode;

            p = (PNDIS_802_11_AUTHENTICATION_MODE) InformationBuffer;
            if(sme_get_auth_mode(pcore_data, &auth_mode) != -1)
			{
				#ifdef _PE_OID_DUMP_
				//_asm{int 3}
				WBDEBUG(("GET Auth mode = %x\n", auth_mode));
				#endif
				switch(auth_mode)
				{
					case OPEN_AUTH:
						*p = Ndis802_11AuthModeOpen;
						break;
					case SHARE_AUTH:
						*p = Ndis802_11AuthModeShared;
						break;
					case ANY_AUTH:
						*p = Ndis802_11AuthModeAutoSwitch;
						break;
					case WPA_AUTH:
						*p = Ndis802_11AuthModeWPA;
						break;
					case WPAPSK_AUTH:
						*p = Ndis802_11AuthModeWPAPSK;
						break;
					case WPANONE_AUTH:
						*p = Ndis802_11AuthModeWPANone;
						break;
					#ifdef _WPA2_
					case WPA2_AUTH:                   //for WPA2 added by WS 19/4/04
						*p = Ndis802_11AuthModeWPA2;
						break;
					case WPA2PSK_AUTH:
						*p = Ndis802_11AuthModeWPA2PSK;//for WPA2 added by WS 19/4/04
					    break;
					#endif //end def _WPA2_
					default:
						break;
				}
			}
        }
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    //case OID_802_11_WEP_STATUS:
	case OID_802_11_ENCRYPTION_STATUS: // same as OID_802_11_WEP_STATUS

        bytes_needed = sizeof(NDIS_802_11_WEP_STATUS);

        if(bytes_needed <= InformationBufferLength)
        {
			//----------------------------------------------------------
			PNDIS_802_11_ENCRYPTION_STATUS	p = (PNDIS_802_11_ENCRYPTION_STATUS) InformationBuffer;
			UCHAR EncryptStatus;

			sme_get_encryption_status(pcore_data, &EncryptStatus);
			#ifdef _PE_OID_DUMP_
			//_asm{int 3}
			WBDEBUG(("GET encrypt status = %x\n", EncryptStatus));
			#endif
			switch (EncryptStatus)
			{
				/*
				case ENCRYPT_NOTSUPPORT:
					*p = Ndis802_11EncryptionNotSupported;
					break;
				*/
				case ENCRYPT_DISABLE:
					*p = Ndis802_11EncryptionDisabled;
					break;
				case ENCRYPT_WEP:
					*p = Ndis802_11Encryption1Enabled;
					break;
				case ENCRYPT_WEP_NOKEY:
					*p = Ndis802_11Encryption1KeyAbsent;
					break;
				case ENCRYPT_TKIP:
					*p = Ndis802_11Encryption2Enabled;
					break;
				case ENCRYPT_TKIP_NOKEY:
					*p = Ndis802_11Encryption2KeyAbsent;
					break;
				case ENCRYPT_CCMP:
					*p = Ndis802_11Encryption3Enabled;
					break;
				case ENCRYPT_CCMP_NOKEY:
					*p = Ndis802_11Encryption3KeyAbsent;
					break;
				default:
					*p = Ndis802_11EncryptionNotSupported;
					break;
			}
			//----------------------------------------------------------
        }
        break;
	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_ASSOCIATION_INFORMATION:
        //WBDEBUG(("[DRV] OID_802_11_ASSOCIATION_INFORMATION (QUERY)\n"));

		bytes_needed = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) +
						psSME->AssocReqVarLen + psSME->AssocRespVarLen;

        //PDEBUG(("[DRV] byte_needed = %d\n", bytes_needed));
        //PDEBUG(("[DRV] InfoBufferLength = %d\n", InfoBufferLength));
        if (bytes_needed <= InformationBufferLength)
        {
            NDIS_802_11_ASSOCIATION_INFORMATION *p;
            UCHAR  *pie;
            UCHAR  conn_status;

            p = (NDIS_802_11_ASSOCIATION_INFORMATION *) InformationBuffer;

			//WBDEBUG(("addr of conn_status = %x\n", &conn_status));
            sme_get_connect_status(pcore_data, &conn_status);

            if (conn_status == MEDIA_STATE_CONNECTED)
            {
                p->Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
                // Association Request
                p->AvailableRequestFixedIEs =
                            NDIS_802_11_AI_REQFI_CAPABILITIES |
                            NDIS_802_11_AI_REQFI_LISTENINTERVAL;
				if (psSME->boReassoc)
					p->AvailableRequestFixedIEs |= NDIS_802_11_AI_REQFI_CURRENTAPADDRESS;

				//p->RequestFixedIEs.Capabilities		= pcore_data->sSmePara.wCapabilityInfo;
				p->RequestFixedIEs.Capabilities =
						pcore_data->asBSSDescriptElement[pcore_data->sLocalPara.wConnectedSTAindex].CapabilityInformation.wValue;
				p->RequestFixedIEs.ListenInterval	= pcore_data->sLocalPara.ListenInterval;
				if (psSME->boReassoc)
				OS_MEMORY_COPY( p->RequestFixedIEs.CurrentAPAddress,
								pcore_data->asBSSDescriptElement[pcore_data->sLocalPara.wConnectedSTAindex].abBssID,
								MAC_ADDR_LENGTH );

                p->RequestIELength = psSME->AssocReqVarLen;
                p->OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);

                // Association Response
                p->AvailableResponseFixedIEs =
                            NDIS_802_11_AI_RESFI_CAPABILITIES |
                            NDIS_802_11_AI_RESFI_STATUSCODE |
                            NDIS_802_11_AI_RESFI_ASSOCIATIONID;
				//TODO:
                p->ResponseFixedIEs.Capabilities    = psSME->AssocRespCapability;
                p->ResponseFixedIEs.StatusCode      = psSME->AssocRespStatus;
				p->ResponseFixedIEs.AssociationId	= pcore_data->sLocalPara.Association_ID&0x3fff;
				#ifdef _PE_OID_DUMP_
				WBDEBUG(("AID =%x\n", p->ResponseFixedIEs.AssociationId));
				#endif

                p->ResponseIELength = psSME->AssocRespVarLen;
                p->OffsetResponseIEs =
                            sizeof(NDIS_802_11_ASSOCIATION_INFORMATION)+
                            psSME->AssocReqVarLen;


                pie = ((UCHAR*) p) + sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
				OS_MEMORY_COPY( pie, psSME->AssocReqVarIE, psSME->AssocReqVarLen );

                pie += psSME->AssocReqVarLen;
				OS_MEMORY_COPY( pie, psSME->AssocRespVarIE, psSME->AssocRespVarLen );
				#ifdef _PE_STATE_DUMP_
				WBDEBUG(("ASSOCIATION INFORMATION\n"));
                DataDmp((UCHAR *)p, p->Length+psSME->AssocReqVarLen+psSME->AssocRespVarLen, 0);
				#endif
                bytes_needed = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION)+
                               psSME->AssocReqVarLen+psSME->AssocRespVarLen;
			//--------------------------------------------------------
            }
        }
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_TX_POWER_LEVEL:
        bytes_needed = sizeof(NDIS_802_11_TX_POWER_LEVEL);

        if(bytes_needed <= InformationBufferLength)
        {
            ULONG   *p;

            p = (NDIS_802_11_TX_POWER_LEVEL *) InformationBuffer;
            sme_get_tx_power_level(pcore_data, p);
        }
		break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_NUMBER_OF_ANTENNAS:
        bytes_needed = sizeof(ULONG);

        if(bytes_needed <= InformationBufferLength)
        {
            ULONG   *p;

            p = (ULONG *) InformationBuffer;
            sme_get_antenna_count(pcore_data, p);
        }
		break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_RX_ANTENNA_SELECTED:
        bytes_needed = sizeof(ULONG);

        if(bytes_needed <= InformationBufferLength)
        {
            ULONG   *p;

            p = (ULONG *) InformationBuffer;
            sme_get_rx_antenna(pcore_data, p);
        }
		break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_TX_ANTENNA_SELECTED:
        bytes_needed = sizeof(ULONG);

        if(bytes_needed <= InformationBufferLength)
        {
            ULONG   *p;

            p = (ULONG *) InformationBuffer;
            sme_get_tx_antenna(pcore_data, p);
        }
		break;

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	//added by ws 04/29/04
	#ifdef _WPA2_
	case OID_802_11_CAPABILITY:
	{
	    static NDIS_802_11_AUTHENTICATION_ENCRYPTION Suppt_AUTH_ENCR_MODE[14]=
			   {
			    {Ndis802_11AuthModeOpen,    Ndis802_11EncryptionDisabled},
				{Ndis802_11AuthModeOpen,    Ndis802_11Encryption1Enabled},
				{Ndis802_11AuthModeShared,  Ndis802_11EncryptionDisabled},
				{Ndis802_11AuthModeShared,  Ndis802_11Encryption1Enabled},
				{Ndis802_11AuthModeWPA,     Ndis802_11Encryption2Enabled},
				{Ndis802_11AuthModeWPA,     Ndis802_11Encryption3Enabled},
				{Ndis802_11AuthModeWPAPSK,  Ndis802_11Encryption2Enabled},
				{Ndis802_11AuthModeWPAPSK,  Ndis802_11Encryption3Enabled},
				{Ndis802_11AuthModeWPANone, Ndis802_11Encryption2Enabled},
				{Ndis802_11AuthModeWPANone, Ndis802_11Encryption3Enabled},
				{Ndis802_11AuthModeWPA2,    Ndis802_11Encryption2Enabled},
				{Ndis802_11AuthModeWPA2,    Ndis802_11Encryption3Enabled},
				{Ndis802_11AuthModeWPA2PSK, Ndis802_11Encryption2Enabled},
				{Ndis802_11AuthModeWPA2PSK, Ndis802_11Encryption3Enabled}
               };

		//PDEBUG(("[DRV] OID_802_11_CAPABIlITY(QUERY)\n"));
        bytes_needed = sizeof(NDIS_802_11_CAPABILITY)
                       +sizeof(NDIS_802_11_AUTHENTICATION_ENCRYPTION)*13;

		if(bytes_needed <=InformationBufferLength)
		{
			PNDIS_802_11_CAPABILITY p=(PNDIS_802_11_CAPABILITY) InformationBuffer;
            p->Length=bytes_needed;
			p->Version=2;
			p->NoOfPMKIDs=16;
			p->NoOfAuthEncryptPairsSupported=sizeof(Suppt_AUTH_ENCR_MODE)
                                             /sizeof(Suppt_AUTH_ENCR_MODE[0]);
            OS_MEMORY_COPY( p->AuthenticationEncryptionSupported, Suppt_AUTH_ENCR_MODE, sizeof(Suppt_AUTH_ENCR_MODE) );
			
		}
	}
	break;//added by ws 
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	case OID_802_11_PMKID:
          {
           NDIS_802_11_PMKID *p=(PNDIS_802_11_PMKID)InformationBuffer;
		   bytes_needed=sizeof(psSME->PmkIdTable);
		   if(bytes_needed <=InformationBufferLength)
		   {
		     p->Length=((NDIS_802_11_PMKID *)psSME->PmkIdTable)->Length;
		     p->BSSIDInfoCount=((NDIS_802_11_PMKID *)psSME->PmkIdTable)->BSSIDInfoCount;
		     OS_MEMORY_COPY( p->BSSIDInfo,
							 ((NDIS_802_11_PMKID*)psSME->PmkIdTable)->BSSIDInfo,
							 sizeof(BSSID_Info)* p->BSSIDInfoCount );
             }
           }
		break;//added by ws
	#endif //end def _WPA2_
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	case OID_802_11_DESIRED_RATES://added by ws 08/04/04 
		{
			//TODO : [1004]
			NDIS_802_11_RATES *p=(NDIS_802_11_RATES *)InformationBuffer;

			bytes_needed=sizeof(NDIS_802_11_RATES);
			if(bytes_needed < InformationBufferLength)
			{
				//memcpy(p,&psLOCAL->CurrentTxRate,sizeof(NDIS_802_11_RATES));//??
				*(*p+0) = (UCHAR)Adapter->WbNdis.TxRateShowResult; //psLOCAL->CurrentTxRate;
				*(*p+1) = 0;
			}
		}
		break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_POWER_MODE:

        bytes_needed = sizeof(NDIS_802_11_POWER_MODE);

        if(bytes_needed <= InformationBufferLength)
        {
            NDIS_802_11_POWER_MODE	*p;
			UCHAR		PowerMode;

            p = (NDIS_802_11_POWER_MODE *) InformationBuffer;
            sme_get_power_mode(pcore_data, &PowerMode);
			*p = PowerMode;
        }
        break;

	#if 0
	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	case OID_802_11_MEDIA_STREAM_MODE:
 
       bytes_needed = sizeof(NDIS_802_11_MEDIA_STREAM_MODE);

        if(bytes_needed <= InformationBufferLength)
        {
            NDIS_802_11_MEDIA_STREAM_MODE	*p;

            p = (NDIS_802_11_MEDIA_STREAM_MODE *) InformationBuffer;
			*p = Ndis802_11MediaStreamOff;
        }
        break;
	#endif

	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	case OID_802_11_CUST_LINK_QUALITY://added by ws 07/26/04
		{
	       PULONG p = (PULONG)InformationBuffer;
	       bytes_needed = sizeof(ULONG);

	   		if (InformationBufferLength >= bytes_needed)
				*p = hal_get_est_sq3( &Adapter->sHwData, 5 ); // Average filter parameter = 5( more smooth)
		}
		break;

	case OID_802_11_CUST_HW_VERSION:
	     {
	       ULONG *p=(ULONG *)InformationBuffer;
	       bytes_needed = sizeof(ULONG);

		   if (InformationBufferLength >= bytes_needed)
				*p = 0x0200; // Only support FB5886
	      }
	      break;
	case OID_802_11_CUST_DRV_VERSION:
	      {
			//TODO : [1004]
	        USHORT * p=(USHORT *)InformationBuffer;
	        bytes_needed=sizeof(USHORT)*4;
	        if(bytes_needed <=InformationBufferLength)
	           {
				PUCHAR	pVerStr = VER_FILEVERSION_STR;
				USHORT	i, k, stmp;
	        
				i = 0;
				k = 0;
				stmp = 0;
				while( pVerStr[i] )
				{
					if( pVerStr[i] == '.' )
					{
						p[k] = stmp;
						k++;
						stmp = 0;
					}
					else
					{
						stmp *= 10;
						stmp += pVerStr[i] - 0x30;
					}
					i++;
				}
				p[k] = stmp;
	            }
	        }//ws
		break;

#ifdef NDIS50_MINIPORT
	case OID_802_11_CUST_DRV_NAME://for window 98 and me only
		if(NULL != InformationBuffer && InformationBufferLength >= g_String.Length)
		{
			ANSI_STRING *global_String=&g_String;
			bytes_needed = g_String.Length;
			NdisMoveMemory(InformationBuffer,global_String->Buffer,global_String->Length);
			#ifdef _PE_STATE_DUMP_
			WBDEBUG(("[WS]OID_802_11_CUST_DRV_NAME %s \n %x \n",InformationBuffer,bytes_needed));
			#endif
		}
		else
			ret = NDIS_STATUS_FAILURE;

		break;
#endif  

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_CUST_RADIO:

        bytes_needed = sizeof(WLAN_RADIO_STATUS);

		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("[QUERY RADIO OID]\n"));
		#endif

        if(bytes_needed <= InformationBufferLength)
        {
            WLAN_RADIO_STATUS   *p;
			RadioOff		RadioOffData;

            p = (WLAN_RADIO_STATUS *) InformationBuffer;
			// 1: off, 0: on
			sme_get_radio_mode(pcore_data, &RadioOffData);
			p->HWStatus = RadioOffData.boHwRadioOff;	//fist cut is always on
			p->SWStatus = RadioOffData.boSwRadioOff;
        }
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_CUST_REGION:

        bytes_needed = sizeof(ULONG);

		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("[QUERY REGION OID]\n"));
		#endif

        if(bytes_needed <= InformationBufferLength)
        {
            ULONG   *p;

            p = (ULONG *) InformationBuffer;
			*p = psLOCAL->region;
        }
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	// 20041102 1.1.91.1000 ybjiang
	case OID_802_11_CUST_REGION_CAPABILITIES:
	    {
			phw_data_t pHwData = &Adapter->sHwData;
			ULONG i, j, Item;
			CHAN_LIST	ChanForRegionCap[6];	//support 6 region
			UCHAR PhyType, EEPROMRegion;
			UCHAR	aRegion[6] = {1,2,3,4,5,6};

			bytes_needed = 0;

			hal_get_phy_type( pHwData, &PhyType );
			EEPROMRegion = hal_get_region_from_EEPROM( pHwData );

			if( EEPROMRegion != REGION_AUTO )
			{
				switch( EEPROMRegion )
				{
					case 2: JAPAN_ChanRange( Adapter, PhyType, ChanForRegionCap ); break;
					case 3: USA_ChanRange( Adapter, PhyType, ChanForRegionCap ); break;
					case 4: FRANCE_ChanRange( Adapter, PhyType, ChanForRegionCap ); break;
					case 5: SPAIN_ChanRange( Adapter, PhyType, ChanForRegionCap ); break;
					case 6: ISRAEL_ChanRange( Adapter, PhyType, ChanForRegionCap ); break;
					default: EUROPE_ChanRange( Adapter, PhyType, ChanForRegionCap ); break;
				}
				Item = 1;
				aRegion[0] = EEPROMRegion;
			}
			else
			{
				EUROPE_ChanRange(Adapter, PhyType, ChanForRegionCap+0);
				JAPAN_ChanRange(Adapter, PhyType, ChanForRegionCap+1);
				USA_ChanRange(Adapter, PhyType, ChanForRegionCap+2);

				FRANCE_ChanRange(Adapter, PhyType, ChanForRegionCap+3);
				SPAIN_ChanRange(Adapter, PhyType, ChanForRegionCap+4);
				ISRAEL_ChanRange(Adapter, PhyType, ChanForRegionCap+5);

				Item = 6;
			}

			// calculate required memory size
			for (i = 0; i < Item; ++i)
			{
				bytes_needed += sizeof(WLAN_REGION_CHANNELS) - sizeof(ULONG);

				bytes_needed += sizeof(ULONG) * ChanForRegionCap[i].Count;
			}

			// include WLAN_REGION_CAPABILITIES::NumberOfItems
			bytes_needed += sizeof(ULONG);

			if (InformationBufferLength >= bytes_needed)
			{
				WLAN_REGION_CAPABILITIES *Capa = (WLAN_REGION_CAPABILITIES*) InformationBuffer;
				WLAN_REGION_CHANNELS *Channels = &Capa->Region[0];
				UCHAR *name, *pntmp;
				ULONG freq;
				UCHAR	NetworkType;
				USHORT StrLen;

				Capa->NumberOfItems = Item;	//EUROPE, JAPAN, USA

				for (i=0; i<Item; ++i)
				{
					Channels->Code = aRegion[i];
					
					pntmp = get_name_of_region(aRegion[i]);
					name = Channels->Name;
					StrLen = (USHORT)strlen(pntmp);
					NdisMoveMemory(name, pntmp, StrLen);
					name += StrLen;

					//FreqArry = get_channels_of_region(region);
					for (j=0; j<ChanForRegionCap[i].Count; j++)
					{
						if (ChanForRegionCap[i].Channel[j].band == BAND_TYPE_DSSS)
							NetworkType = Ndis802_11DS;
						else if (ChanForRegionCap[i].Channel[j].band == BAND_TYPE_OFDM_24)
							NetworkType = Ndis802_11OFDM24;
						else if (ChanForRegionCap[i].Channel[j].band == BAND_TYPE_OFDM_5)
							NetworkType = Ndis802_11OFDM5;
						ChannelNumToFreq( NetworkType, ChanForRegionCap[i].Channel[j].ChanNo, &freq );
						Channels->Frequency[j] = freq;

						if (ChanForRegionCap[i].Channel[j].band > BAND_TYPE_OFDM_24)
						{
							StrLen = ChanNo2String(ChanForRegionCap[i].Channel[j].ChanNo, name);
							name += StrLen;
						}
					}
					Channels->Length = sizeof(WLAN_REGION_CHANNELS) - sizeof(ULONG) + j * sizeof(ULONG);
					*(name-1) = '\0';	//replace last ','
					Channels->NameLength = strlen(Channels->Name);

					// move to the next structure
					Channels = (WLAN_REGION_CHANNELS*) ((UCHAR*) Channels + Channels->Length);
				}
				#ifdef _PE_STATE_DUMP_
				WBDEBUG(("** dump Query OID_802_11_CUST_REGION_CAPABILITIES **\n"));
				DataDmp((UCHAR *)Capa, bytes_needed, 0);
				#endif
			}
		}
		break;
    //--------------------------------------------------------------------------
      case OID_802_11_CUST_ENCRYPTION_STATUS:
        
		bytes_needed = sizeof(ULONG);
        
		if (InformationBufferLength >= bytes_needed)
		{    
		     //WBDEBUG(("[WS]the wepkey error =%d",pcore_data->sLocalPara.bWepKeyError));
			 *(ULONG *) InformationBuffer = pcore_data->sLocalPara.bWepKeyError;
		}
		break;

	//sky added 20050803
	//----------------------------------------------------------------------------
	  case OID_802_11_CUST_TX_THROUGHPUT:
			bytes_needed = sizeof(ULONG);
			if (InformationBufferLength >= bytes_needed)
			{
				*(ULONG *) InformationBuffer = pcore_data->WbNdis.TxByteCount;
			}
			break;

	//---------------------------------------------------------------------------
	  case OID_802_11_CUST_RX_THROUGHPUT:
			bytes_needed = sizeof(ULONG);
			if (InformationBufferLength >= bytes_needed)
			{
				*(ULONG *) InformationBuffer = pcore_data->WbNdis.RxByteCount;
			}
			break;

	//----------------------------------------------------------------------------
	  //sky added 2005.0817 
	  case OID_802_11_CUST_RF_TYPE:
			bytes_needed = sizeof(UCHAR);
			if (InformationBufferLength >= bytes_needed)
			{
				*(UCHAR *) InformationBuffer = pcore_data->sHwData.phy_type;
			}
			break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    default:
        ret = WB_NDIS_STATUS_NOT_SUPPORTED;
    }

    *pMoveBytes = bytes_needed;

    return ret;
}

/****************************************************************************/
/* translate bss description to NDIS_WLAN_BSSID */
void drv_translate_bss_ex( IN PWB32_ADAPTER Adapter, NDIS_WLAN_BSSID_EX *pndis_bss, bss_desc_tt *pbss )
{
    PNDIS_802_11_CONFIGURATION  pconfig;
	ULONG channel_freq = 0;

	//TODO:
    /* Length */
    //pndis_bss->Length = (sizeof(NDIS_WLAN_BSSID_EX) -4 + pbss->ies_len + 3)  & ~0x03;
	// 20061108 WPS
	pndis_bss->Length = (sizeof(NDIS_WLAN_BSSID_EX) -4 + pbss->ies_len + pbss->WPS_IE_length + 3)  & ~0x03;

    /* MacAddress */
    NdisMoveMemory(pndis_bss->MacAddress, pbss->abBssID, 6);

    /* Ssid */
    pndis_bss->Ssid.SsidLength = pbss->SSID.Length;
    NdisMoveMemory(pndis_bss->Ssid.Ssid, pbss->SSID.SSID, pbss->SSID.Length);

    /* Privacy */
    pndis_bss->Privacy = pbss->CapabilityInformation.Capability.CF_Privacy;

    /* RSSI */
	if( OS_RSSI_TEST_SET( Adapter ) )
		pndis_bss->Rssi = OS_RSSI_TEST_SET( Adapter );
	else
		pndis_bss->Rssi = hal_get_rssi( &Adapter->sHwData, pbss->HalRssi, 1 ); // 20060329 modify for real

    /* NetworkTypeInUse */
	if (pbss->DS_Parameter_Set.Current_Channel >14)
		pndis_bss->NetworkTypeInUse = Ndis802_11OFDM5;
	else
	{
		if (pbss->boERP)
			pndis_bss->NetworkTypeInUse = Ndis802_11OFDM24;
		else
			pndis_bss->NetworkTypeInUse = Ndis802_11DS;
	}

    /* Configuration */
    pconfig = &(pndis_bss->Configuration);
    pconfig->Length         = sizeof(NDIS_802_11_CONFIGURATION);
    pconfig->BeaconPeriod   = pbss->Beacon_Period;
    pconfig->ATIMWindow     = *((PUSHORT)pbss->IBSS_Parameter_Set.ATIM_Window);//Current ATIMWindow
	ChannelNumToFreq(pndis_bss->NetworkTypeInUse,
							pbss->DS_Parameter_Set.Current_Channel,
							&channel_freq);
	pconfig->DSConfig = channel_freq * 1000;

    pconfig->FHConfig.Length = sizeof(NDIS_802_11_CONFIGURATION_FH);
    pconfig->FHConfig.HopPattern    = 0;
    pconfig->FHConfig.HopSet        = 0;
    pconfig->FHConfig.DwellTime     = 0;

    /* InfrastructureMode (BSS mode setting) */
    pndis_bss->InfrastructureMode = pbss->CapabilityInformation.Capability.ESS ? \
											Ndis802_11Infrastructure : Ndis802_11IBSS;
    /* SupportRates */
    NdisMoveMemory(pndis_bss->SupportedRates,
                   pbss->SupportedRateSet.SupportedRates,
                   pbss->SupportedRateSet.Length);
	pndis_bss->SupportedRates[pbss->SupportedRateSet.Length] = 0;

	//TODO:
    //pndis_bss->IELength = 0;
    pndis_bss->IELength = pbss->ies_len;
    NdisMoveMemory(pndis_bss->IEs, pbss->ies, pbss->ies_len);

	// 20061108 Add WPS IE
	if( pbss->WPS_IE_length )
	{
		pndis_bss->IELength += pbss->WPS_IE_length;
		NdisMoveMemory( (PUCHAR)pndis_bss->IEs + pbss->ies_len, pbss->WPS_IE_Data, pbss->WPS_IE_length );
	}
}

NDIS_STATUS Ndis51SetInformation( IN PWB32_ADAPTER pcore_data,
								  IN NDIS_OID Oid,
								  IN PVOID InformationBuffer,
								  IN ULONG InformationBufferLength,
								  OUT PULONG	pBytesNeed)
{
	NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
	PWB32_ADAPTER Adapter = pcore_data;
	PNDIS51_DESIRED_PARAMETER pN51 = &Adapter->DesiredNdis51Parameter;

	#ifdef _PE_OID_DUMP_
	DbgPrintfOID51(Oid, FALSE);
	#endif

	*pBytesNeed =0;


	if( TS_RUNNING_IN_TESTSTA_MODE )
		return StatusToReturn;

	switch(Oid)
	{
	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	//case OID_802_11_WEP_STATUS:
	case OID_802_11_ENCRYPTION_STATUS: // same as OID_802_11_WEP_STATUS

		if(InformationBufferLength >= sizeof(NDIS_802_11_WEP_STATUS))
		{
			PNDIS_802_11_ENCRYPTION_STATUS	p = (PNDIS_802_11_ENCRYPTION_STATUS)InformationBuffer;
			UCHAR EncryptStatus;

			switch (*p)
			{
				case Ndis802_11EncryptionNotSupported:
					//EncryptStatus = ENCRYPT_NOTSUPPORT;
					EncryptStatus = ENCRYPT_DISABLE;
                    psSME->DesiredEncrypt=Cipher_Disabled;//added by ws 04/22/05
					break;
				case Ndis802_11EncryptionDisabled:
					EncryptStatus = ENCRYPT_DISABLE;
                    psSME->DesiredEncrypt=Cipher_Disabled;
					break;
				case Ndis802_11Encryption1Enabled:
					EncryptStatus = ENCRYPT_WEP;
                    psSME->DesiredEncrypt=Cipher_Wep;
					break;
				case Ndis802_11Encryption1KeyAbsent:
					EncryptStatus = ENCRYPT_WEP_NOKEY;
                    psSME->DesiredEncrypt=Cipher_Wep;
					break;
				case Ndis802_11Encryption2Enabled:
					EncryptStatus = ENCRYPT_TKIP;
                    psSME->DesiredEncrypt=Cipher_Tkip;
					break;
				case Ndis802_11Encryption2KeyAbsent:
					EncryptStatus = ENCRYPT_TKIP_NOKEY;
                    psSME->DesiredEncrypt=Cipher_Tkip;
					break;
				case Ndis802_11Encryption3Enabled:
					EncryptStatus = ENCRYPT_CCMP;
                    psSME->DesiredEncrypt=Cipher_Ccmp;
					break;
				case Ndis802_11Encryption3KeyAbsent:
					EncryptStatus = ENCRYPT_CCMP_NOKEY;
                    psSME->DesiredEncrypt=Cipher_Ccmp;
					break;
				default:
					EncryptStatus = ENCRYPT_DISABLE;
                    psSME->DesiredEncrypt=Cipher_Disabled;
					break;
			}
			sme_set_encryption_status(pcore_data, EncryptStatus);
			#ifdef _PE_OID_DUMP_
			WBDEBUG(("SET Encrypt status = %x\n", EncryptStatus));
			#endif
		}
		else
			StatusToReturn = NDIS_STATUS_NOT_ACCEPTED;
		break;

	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	case OID_802_11_FRAGMENTATION_THRESHOLD:

		if(InformationBufferLength >= sizeof(NDIS_802_11_FRAGMENTATION_THRESHOLD))
		{
			NDIS_802_11_FRAGMENTATION_THRESHOLD	TxFragThres;

			TxFragThres = *((NDIS_802_11_FRAGMENTATION_THRESHOLD *)InformationBuffer);

			if(sme_set_fragment_threshold(pcore_data, TxFragThres) == -1)
				StatusToReturn = NDIS_STATUS_INVALID_DATA;
		}
		else
			*pBytesNeed = sizeof(NDIS_802_11_FRAGMENTATION_THRESHOLD);
		break;

	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	case OID_802_11_RTS_THRESHOLD:

		if(InformationBufferLength >= sizeof(NDIS_802_11_RTS_THRESHOLD))
		{
			NDIS_802_11_RTS_THRESHOLD RtsThres;

			RtsThres = *((NDIS_802_11_RTS_THRESHOLD *)InformationBuffer);

			if(sme_set_rts_threshold(pcore_data, RtsThres) == -1)
				StatusToReturn = NDIS_STATUS_INVALID_DATA;
		}
		else
			*pBytesNeed = sizeof(NDIS_802_11_RTS_THRESHOLD);
		break;

	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	case OID_802_11_ADD_WEP:

		if(InformationBufferLength >= sizeof(NDIS_802_11_WEP))
		{
			PNDIS_802_11_WEP pWEPdata = (PNDIS_802_11_WEP)InformationBuffer;
			UCHAR bssid[MAC_ADDR_LENGTH];

			//WBDEBUG(("addr of bssid = %x\n", bssid));
			sme_get_bssid(pcore_data, bssid);
			if(sme_set_add_wep(pcore_data,
								 pWEPdata->KeyIndex,
								 pWEPdata->KeyLength,
								 bssid, //address
								 pWEPdata->KeyMaterial)==-1)
				StatusToReturn = NDIS_STATUS_INVALID_DATA;
			sme_set_encryption_status(pcore_data, ENCRYPT_WEP);

		}
		else
			*pBytesNeed = sizeof(NDIS_802_11_WEP);

		break;

	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	case OID_802_11_REMOVE_WEP:

			if(InformationBufferLength >= sizeof(NDIS_802_11_KEY_INDEX))
			{
				NDIS_802_11_KEY_INDEX KeyIndex;

				KeyIndex = *((NDIS_802_11_KEY_INDEX *)InformationBuffer);
				#ifdef _PE_OID_DUMP_
				WBDEBUG(("OID_ Removing Key[%x]\n", KeyIndex));
				#endif

				if (sme_set_remove_wep(pcore_data, KeyIndex) == -1)
				{
					#ifdef _PE_OID_DUMP_
					WBDEBUG(("OID_802_11_REMOVE_WEP fail!\n"));
					#endif
					StatusToReturn = NDIS_STATUS_INVALID_DATA;
				}
			}
			else
				*pBytesNeed = sizeof(NDIS_802_11_KEY_INDEX);

			break;

	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	case OID_802_11_INFRASTRUCTURE_MODE:

		if(InformationBufferLength >= sizeof(NDIS_802_11_NETWORK_INFRASTRUCTURE))
		{
			NDIS_802_11_NETWORK_INFRASTRUCTURE BSSmode;
			UCHAR BssType;

			//[20060824] Added to avoid the reissue of this OID even in the CONNECT state
			sme_set_disassociate(Adapter);

			BSSmode = *((NDIS_802_11_NETWORK_INFRASTRUCTURE *)InformationBuffer);
			BssType = (BSSmode == Ndis802_11IBSS) ? IBSS_NET : ESS_NET;
			sme_set_desired_bss_type(pcore_data, BssType);
			#ifdef _PE_OID_DUMP_
			WBDEBUG(("OID: set infrastructure mode=%x\n", BssType));
			#endif
		}
		else
			*pBytesNeed = sizeof(NDIS_802_11_NETWORK_INFRASTRUCTURE);
		break;

	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	case OID_802_11_CONFIGURATION:

		if(InformationBufferLength >= sizeof(NDIS_802_11_CONFIGURATION))
		{
			PNDIS_802_11_CONFIGURATION	pConfig = (PNDIS_802_11_CONFIGURATION)InformationBuffer;
			ULONG	ChanFreq;
			ChanInfo chan;

			sme_set_beacon_period(pcore_data, (USHORT)pConfig->BeaconPeriod);
			sme_set_atim_window(pcore_data, (USHORT)pConfig->ATIMWindow);
			ChanFreq = pConfig->DSConfig/1000;	//convert to MHz
			if (ChanFreq >= 3000)
				chan.band = BAND_TYPE_OFDM_5;
			else
				chan.band = BAND_TYPE_OFDM_24;
			FreqToChannelNum(chan.band,
								&chan.ChanNo,
								ChanFreq);
			sme_set_IBSS_chan(pcore_data, chan);
		}
		else
			*pBytesNeed = sizeof(NDIS_802_11_CONFIGURATION);
		break;

	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	case OID_802_11_AUTHENTICATION_MODE:
		if(InformationBufferLength >= sizeof(NDIS_802_11_AUTHENTICATION_MODE))
		{
			NDIS_802_11_AUTHENTICATION_MODE NdisAuthMode = *((PNDIS_802_11_AUTHENTICATION_MODE)InformationBuffer);
			UCHAR auth_mode;

			switch(NdisAuthMode)
			{
				case Ndis802_11AuthModeOpen:
					auth_mode = OPEN_AUTH;
					break;
				case Ndis802_11AuthModeShared:
					auth_mode = SHARE_AUTH;
					break;
				case Ndis802_11AuthModeAutoSwitch:
					auth_mode = ANY_AUTH;
					break;
				case Ndis802_11AuthModeWPA:
					auth_mode = WPA_AUTH;
					break;
				case Ndis802_11AuthModeWPAPSK:
					auth_mode = WPAPSK_AUTH;
					break;
				case Ndis802_11AuthModeWPANone:
					auth_mode = WPANONE_AUTH;
					break;
				#ifdef _WPA2_
				case Ndis802_11AuthModeWPA2:
					auth_mode = WPA2_AUTH;
					break;
				case Ndis802_11AuthModeWPA2PSK:
					auth_mode = WPA2PSK_AUTH;
                    break;
				#endif //end def _WPA2_
				default:
					StatusToReturn = NDIS_STATUS_INVALID_DATA;
					break;
			}
			if (StatusToReturn != NDIS_STATUS_INVALID_DATA)
			{
				sme_set_auth_mode(pcore_data, auth_mode);
				#ifdef _PE_OID_DUMP_
				WBDEBUG(("SET Auth mode = %x\n", auth_mode));
				#endif
			}
		}
		else
			*pBytesNeed = sizeof(NDIS_802_11_AUTHENTICATION_MODE);
		break;

	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	//Real-time service with pending return if needed
	case OID_802_11_BSSID:
		if( InformationBufferLength >= 6 )
		{
			sme_set_desired_bssid(pcore_data, InformationBuffer);
		}
		else
			*pBytesNeed = 6;

		break;

	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	case OID_802_11_SSID:

		if( InformationBufferLength >= sizeof(NDIS_802_11_SSID) )
		{
			PNDIS_802_11_SSID pSSID = (PNDIS_802_11_SSID)InformationBuffer;

			#ifdef _PE_OID_DUMP_
			UCHAR ssid[50];
			OS_MEMORY_COPY( ssid, (UCHAR *)pSSID->Ssid, (UCHAR)pSSID->SsidLength );
			ssid[pSSID->SsidLength] = '\0';
			WBDEBUG(("SET ssid=%s\n", ssid));
			#endif
			if (pSSID->SsidLength > 32)
			{
				StatusToReturn = NDIS_STATUS_INVALID_DATA;
			}
			else
			{
				PUCHAR	pctmp;
				int	i, AcceptSsid;
				UCHAR boMsRadioOff;

				//Radio on : 0, Radio off : 1
				// ** 20060828 [Anson] DDK2600 and DDK5048 are Different description **
				sme_get_ms_radio_mode(Adapter, &boMsRadioOff);
				if (boMsRadioOff == 1)
					sme_set_ms_radio_mode(Adapter, 0); //Radio On
				psSME->boDUTmode = FALSE;
				OS_MEMORY_COPY( pN51->CurrentSSID, (UCHAR *)pSSID->Ssid, (UCHAR)pSSID->SsidLength );
				pN51->CurrentSSIDLength = pSSID->SsidLength;
				sme_set_desired_ssid(pcore_data, (UCHAR *)pSSID->Ssid, (UCHAR)pSSID->SsidLength);

				pctmp = (UCHAR *)pSSID->Ssid;
				AcceptSsid = 1;
				for( i=0; i<(int)pSSID->SsidLength; i++ )
				{
					if( (pctmp[i]>126) || (pctmp[i]<32 ) )
					{
						AcceptSsid = 0;
						break;
					}
				}
				if( AcceptSsid )
				{
					pN51->ConnectInterval = 8;
					pN51->ConnectCount = 1;
				}
				else
					pN51->ConnectCount = 0;
			}
		}
		else
			*pBytesNeed = sizeof(NDIS_802_11_SSID);

		break;

	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	case OID_802_11_DISASSOCIATE:
		sme_set_disassociate(pcore_data);
		//Radio on : 0, Radio off : 1
		sme_set_ms_radio_mode(Adapter, 1);
		break;

	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	case OID_802_11_BSSID_LIST_SCAN:

		pcore_data->DesiredNdis51Parameter.sync_scan_require = 1;
		NdisMSetTimer( &pcore_data->DesiredNdis51Parameter.scan_sync_timer, 0 );
		break;

	case OID_802_11_RELOAD_DEFAULTS:

		if(InformationBufferLength >= sizeof(NDIS_802_11_RELOAD_DEFAULTS))
		{
			PNDIS_802_11_RELOAD_DEFAULTS pReloadDefaultType = (PNDIS_802_11_RELOAD_DEFAULTS)InformationBuffer;

			if (*pReloadDefaultType == Ndis802_11ReloadWEPKeys)
			{
				sme_set_reload_defaults(Adapter, ENCRYPT_WEP);
			}
			else
				StatusToReturn = NDIS_STATUS_INVALID_DATA;
		}
		else
			*pBytesNeed = sizeof(NDIS_802_11_RELOAD_DEFAULTS);
		break;

   	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	case OID_802_11_ADD_KEY:

        	if (InformationBufferLength >= 37) // 37 for WEP40
    		{
            	NDIS_802_11_KEY *p = (NDIS_802_11_KEY *)InformationBuffer;
	            UCHAR              *ptx_tsc = NULL;
    	        UCHAR              *prx_tsc = NULL;
            	UCHAR              key_type;
				UCHAR				key_len;
				//UCHAR				EncryptStatus;

            	#ifdef _PE_OID_DUMP_
            	WBDEBUG(("[DRV] ** Length   = %d\n", p->Length));
            	WBDEBUG(("[DRV] ** KeyIndex = 0x%08X\n", p->KeyIndex));
            	WBDEBUG(("[DRV] ** KeyLength = %d\n", p->KeyLength));
            	WBDEBUG(("[DRV] ** BSSID = " MACSTR "\n", MAC2STR(p->BSSID)));
            	WBDEBUG(("[DRV] ** KeyRSC (hi) = %d\n", p->KeyRSC >> 32));
            	WBDEBUG(("[DRV] ** KeyRSC (lo) = %d\n", p->KeyRSC));
            	DataDmp(p->KeyMaterial, p->KeyLength, 0);
            	#endif

	            if (p->KeyIndex == 0xC0000001)
    	        {
					#ifdef _PE_OID_DUMP_
        	        WBDEBUG(("** NDIS_STATUS_INVALID_DATA\n"));
					#endif
            	    StatusToReturn = NDIS_STATUS_INVALID_DATA;
            	}
	            else
    	        {	//TODO: ??Should it set encryption status for the some XP OID sequence??
					switch (p->KeyLength)
					{
						case 5:
							//WBDEBUG(("Key Type = WEP40\n"));
							key_type = HAL_KEYTYPE_WEP40;
							key_len = 5;
							//sme_set_encryption_status(Adapter, ENCRYPT_WEP);
							break;
						case 13:
							//WBDEBUG(("Key Type = WEP104\n"));
							key_type = HAL_KEYTYPE_WEP104;
							key_len = 13;
							//sme_set_encryption_status(Adapter, ENCRYPT_WEP);
							break;
						case 16:
							//WBDEBUG(("Key Type = CCMP\n"));
							key_type = HAL_KEYTYPE_AES_CCMP;
							key_len = 16;
							//sme_set_encryption_status(Adapter, ENCRYPT_CCMP);
							break;
						case 32:
							//WBDEBUG(("Key Type = TKIP\n"));
							key_type = HAL_KEYTYPE_TKIP;
							key_len = 16;
							//sme_set_encryption_status(Adapter, ENCRYPT_TKIP);
							break;
						default:
							//WBDEBUG(("Key Type = UNKNOWN\n"));
							return NDIS_STATUS_INVALID_DATA;
					}

					if (p->KeyIndex & BIT(29))
					{
						// the KeyRSC should be used to set the initial receive
						// SC for the key when BIT 29 is set to 1.

						// If the encryption cipher needs less bytes than supplied
						// by KeyRSC, the least significant bytes should be used.
						prx_tsc = (UCHAR*) &p->KeyRSC;
					}

					if (sme_add_key(Adapter,
								p->KeyIndex,
								key_len,
								key_type,
								p->BSSID,
								ptx_tsc,
								prx_tsc,
								//p->KeyRSC,
								p->KeyMaterial) == -1)
						return NDIS_STATUS_INVALID_DATA;
            	}
	        }
    	    else
        	{
            	*pBytesNeed = sizeof(NDIS_802_11_KEY);

	            #ifdef _PE_OID_DUMP_
    	        WBDEBUG(("[DRV] ** buffer size (%d) < %d\n", InformationBufferLength, sizeof(NDIS_802_11_KEY)));
        	    DataDmp(InformationBuffer, InformationBufferLength, 0);
            	#endif
	        }
		    break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	case OID_802_11_REMOVE_KEY:
		//WBDEBUG(("[DRV] OID_802_11_REMOVE_KEY (SET)\n"));

		//size = sizeof(NDIS_802_11_REMOVE_KEY);

		if (InformationBufferLength >= sizeof(NDIS_802_11_REMOVE_KEY))
		{
			NDIS_802_11_REMOVE_KEY *p = (NDIS_802_11_REMOVE_KEY *)InformationBuffer;

			#ifdef _PE_OID_DUMP_
			WBDEBUG(("[DRV] ** Length   = %d\n", p->Length));
			WBDEBUG(("[DRV] ** KeyIndex = %d\n", p->KeyIndex));
			WBDEBUG(("[DRV] ** BSSID = " MACSTR "\n", MAC2STR(p->BSSID)));
			#endif
			if ((p->KeyIndex & (~BIT(30))) > 0xff)
			{
				StatusToReturn = NDIS_STATUS_INVALID_DATA;
				break;
			}
			if (BIT(30) == (p->KeyIndex & BIT(30)))
			{
                //if(IS_BROADCAST_BSSID(p->BSSID))
				if( boCmpMacAddr( p->BSSID, "\xff\xff\xff\xff\xff\xff" ) )
                {
                    sme_clear_all_mapping_key(pcore_data);
                }
                else
                {
                    sme_remove_mapping_key(pcore_data, p->BSSID);
                }
			}
			else if (p->KeyIndex < 4)
			{
                sme_remove_default_key(pcore_data, p->KeyIndex & 0xff);
			}
			else
			{
				StatusToReturn = NDIS_STATUS_INVALID_DATA;
                break;
			}
        }
        else
        {
            *pBytesNeed = sizeof(NDIS_802_11_REMOVE_KEY);
        }
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	case OID_802_11_ASSOCIATION_INFORMATION:
	    //WBDEBUG(("[DRV] OID_802_11_ASSOCIATION_INFORMATION (SET)\n"));
	    break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_TEST:
        //WBDEBUG(("[DRV] OID_802_11_TEST (SET)\n"));
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_TX_POWER_LEVEL:
        //WBDEBUG(("[DRV] OID_802_11_TX_POWER_LEVEL (SET)\n"));
		if( InformationBufferLength >= sizeof(ULONG) )
		{
			NDIS_802_11_TX_POWER_LEVEL TxPower= *(NDIS_802_11_TX_POWER_LEVEL *)InformationBuffer;

			sme_set_tx_power_level(Adapter, TxPower);
		}
		else
			*pBytesNeed = sizeof(ULONG);
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_RX_ANTENNA_SELECTED:
        //WBDEBUG(("[DRV] OID_802_11_RX_ANTENNA_SELECTED (SET)\n"));
		if( InformationBufferLength >= sizeof(ULONG) )
		{
			ULONG RxAntenna = *(ULONG *)InformationBuffer;

			sme_set_rx_antenna(Adapter, RxAntenna);
		}
		else
			*pBytesNeed = sizeof(ULONG);
        break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_TX_ANTENNA_SELECTED:
        //WBDEBUG(("[DRV] OID_802_11_TX_ANTENNA_SELECTED (SET)\n"));
		if( InformationBufferLength >= sizeof(ULONG) )
		{
			ULONG TxAntenna = *(ULONG *)InformationBuffer;

			sme_set_tx_antenna(Adapter, TxAntenna);
		}
		else
			*pBytesNeed = sizeof(ULONG);
        break;

	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	case OID_802_11_DESIRED_RATES://added by ws 08/04/04 
		//TODO : [1004]
		//WBDEBUG(("[WS]OID_802_11Desired_rate,the informationBuffer=%x\n",*((NDIS_802_11_RATES *)InformationBuffer)));
		//bytes_needed=sizeof(NDIS_802_11_RATES)*8;
		if(InformationBufferLength >= sizeof(NDIS_802_11_RATES))
		{
			UCHAR *p=(UCHAR *)InformationBuffer;
			int i;

			for (i=0; i<8; ++i)
				if (p[i] == 0)
					break;
			// Use auto tx rate if no rate assigned.
			if (i==1 || i==0)
			{
				//WWU defines "AUTO" as 0(DTO on).
				psLOCAL->TxRateMode = *(UCHAR *)InformationBuffer;
				if (psLOCAL->TxRateMode != RATE_AUTO)
				{
					if (psLOCAL->TxRateMode == RATE_MAX)
					{
						if (psLOCAL->wConnectedSTAindex != 0)
						{
							SetMaxTxRate(Adapter);
						}
						else
						{
							psLOCAL->CurrentTxRate = psLOCAL->CurrentTxRateForMng;
							psLOCAL->CurrentTxFallbackRate = psLOCAL->CurrentTxRate;
						}
					}
					else
					{
						psLOCAL->CurrentTxRate = psLOCAL->TxRateMode;
						psLOCAL->CurrentTxFallbackRate = psLOCAL->CurrentTxRate;
					}
				}
			}
		}
		break;
	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	#ifdef _WPA2_
	case OID_802_11_PMKID://added by ws
		{
			PNDIS_802_11_PMKID p=(PNDIS_802_11_PMKID) InformationBuffer;
            PMKID_Table *PmkIdTable=(PMKID_Table*)pcore_data->sSmePara.PmkIdTable;
            UCHAR i,j;
            BOOL bExistPmkid=FALSE;
            
			for(j=0;j<p->BSSIDInfoCount;j++)
			{
				for(i=0;i<PmkIdTable->BSSIDInfoCount;i++)
				{
					//if PMKID is existing in the PMKID table, it will be stored into the same space.
					if( boCmpMacAddr( PmkIdTable->BSSIDInfo[i].PreAuthBssID, (p->BSSIDInfo + j*sizeof(BSSID_INFO))->BSSID ) )
					{
						OS_MEMORY_COPY( &PmkIdTable->BSSIDInfo[i],
										&p->BSSIDInfo+j*sizeof(BSSID_INFO), sizeof(BSSID_INFO) );
						bExistPmkid=TRUE;
						break;
					}
				}
				//if PMKID is not existing in PMKID table,the PMKID is stored into the available space
				if( !bExistPmkid )
				{
					OS_MEMORY_COPY( &PmkIdTable->BSSIDInfo[psSME->PmkidTableIndex],
									&p->BSSIDInfo+j*sizeof(BSSID_INFO), sizeof(BSSID_INFO) );
					PmkIdTable->Length +=sizeof(BSSID_INFO);
					PmkIdTable->BSSIDInfoCount++;
					if( psSME->PmkidTableIndex > 16 )
						psSME->PmkidTableIndex=0;
					else
						psSME->PmkidTableIndex++;
					bExistPmkid=FALSE;
				}
			}
		}
		break;
	#endif // end def _WPA2_
	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	case OID_802_11_NETWORK_TYPE_IN_USE:
		if(InformationBufferLength >= sizeof(NDIS_802_11_NETWORK_TYPE))
		{
			NDIS_802_11_NETWORK_TYPE	NetworkType;
			UCHAR							OpMode;

			NetworkType = *((NDIS_802_11_NETWORK_TYPE *)InformationBuffer);
			//Check whether the data is correct
			if (NetworkType < Ndis802_11NetworkTypeMax)
			{
				switch (NetworkType)
				{
					case Ndis802_11DS:
						OpMode = MODE_802_11_B;
						break;
					case Ndis802_11OFDM24:
						OpMode = MODE_802_11_BG;
						break;
					case Ndis802_11OFDM5:
						OpMode = MODE_802_11_A;
						break;
					default:
						OpMode = MODE_802_11_BG;
						break;
				}
				sme_set_network_type_in_use(Adapter, OpMode);
			}
			else
                StatusToReturn = NDIS_STATUS_INVALID_DATA;
		}
		else
			*pBytesNeed = sizeof(NDIS_802_11_NETWORK_TYPE);
        break;

	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	case OID_802_11_POWER_MODE:
		if(InformationBufferLength >= sizeof(NDIS_802_11_POWER_MODE))
		{
			NDIS_802_11_POWER_MODE	pPmValue;
			UCHAR	PowerMode;

			pPmValue = *((NDIS_802_11_POWER_MODE *)InformationBuffer);
			PowerMode = (UCHAR)pPmValue;
			#ifdef _PE_STATE_DUMP_
			WBDEBUG(("[Set POWER MODE OID] PowerMode = %d\n", PowerMode));
			#endif
			sme_set_power_mode(Adapter, PowerMode);
		}
		else
			*pBytesNeed = sizeof(NDIS_802_11_POWER_MODE);
        break;

	#if 0
	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	case OID_802_11_MEDIA_STREAM_MODE:
		if(InformationBufferLength >= sizeof(NDIS_802_11_MEDIA_STREAM_MODE))
		{
			#ifdef _PE_STATE_DUMP_
			WBDEBUG(("[Set OID_802_11_MEDIA_STREAM_MODE] = %d\n", *(NDIS_802_11_MEDIA_STREAM_MODE *)InformationBuffer));
			#endif
			StatusToReturn = NDIS_STATUS_SUCCESS;
		}
		else
			*pBytesNeed = sizeof(NDIS_802_11_MEDIA_STREAM_MODE);
        break;
	#endif

	//---------------------------------------------------------------------------------------------
	//added by ws 08/23/04
	case OID_802_11_CUST_PREAMBLE_TYPE:
    
        { 
           //TODO: [1004]
           //WBDEBUG(("[ws]OID_802_11_CUST_PREAMBLE_TYPE\n"));
           if(InformationBufferLength >=sizeof(ULONG))
             {
                ULONG *p=(ULONG*)InformationBuffer;
                if(*p&0x1)
                   psLOCAL->boShortPreamble = 0;    //long preamble
                else 
                   psLOCAL->boShortPreamble = 1; //short preamble                    
                
              }   
         }
          break;   
	//---------------------------------------------------------------------------------------------
	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  	case OID_802_11_CUST_IE_APPEND: // 20061108 WPS
		if( sme_set_IE_append( pcore_data, (PUCHAR)InformationBuffer, (USHORT)InformationBufferLength) )
			StatusToReturn = NDIS_STATUS_FAILURE;
		break;

	case OID_802_11_CUST_LED_CONTROL: // 20061108 WPS LED control
			hal_set_LED( &Adapter->sHwData, *(PULONG)InformationBuffer );
			break;

	case OID_802_11_CUST_RADIO:

		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("[Set RADIO OID]\n"));
		#endif

		if(InformationBufferLength >= sizeof(WLAN_RADIO_STATUS))
		{
			WLAN_RADIO_STATUS *p = (WLAN_RADIO_STATUS *)InformationBuffer;
			RadioOff DesiredRadioOffData, CurrentRadioOffData;;

			//Radio on : 0, Radio off : 1
			DesiredRadioOffData.boSwRadioOff = p->SWStatus;
			DesiredRadioOffData.boHwRadioOff = p->HWStatus;
			#ifdef _PE_STATE_DUMP_
			WBDEBUG(("Set CUST RADIO h/w Radio off = %x, s/w Radio off =%x\n",
									psLOCAL->RadioOffStatus.boHwRadioOff,
									psLOCAL->RadioOffStatus.boSwRadioOff));
			#endif
			sme_get_radio_mode(Adapter, &CurrentRadioOffData);
			CheckRadioOffForDisassoc( Adapter, DesiredRadioOffData, CurrentRadioOffData );
			sme_set_radio_mode(Adapter, DesiredRadioOffData);
		}
		else
			*pBytesNeed = sizeof(WLAN_RADIO_STATUS);

		break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_CUST_REGION:
		if( InformationBufferLength >= sizeof(ULONG) )
		{
            ULONG   *p;

            p = (ULONG *) InformationBuffer;
			psLOCAL->region = (UCHAR)*p;
			//Region has been changed. Reconnect it!!
			GetSupportChanRange(Adapter);
			GetIbssChan(Adapter);
			Scan_SetScanChanRange(Adapter, psSCANREQ);
			sme_set_disassociate(Adapter);
			#ifdef _PE_STATE_DUMP_
			WBDEBUG(("[Set REGION OID] psLOCAL->region = %d\n", psLOCAL->region));
			#endif
		}
		else
			*pBytesNeed = sizeof(ULONG);
        break;

	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	case OID_802_11_CUST_RADIO_NOTIFICATION:

		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("[Set RADIO NOTIFICATION OID]\n"));
		#endif

		if(InformationBufferLength >= sizeof(WLAN_RADIO_NOTIFICATION))
		{
			WLAN_RADIO_NOTIFICATION *p = (WLAN_RADIO_NOTIFICATION *)InformationBuffer;

			// send a radio notification directly
			if (p->RadioChangeHandler != 0 && p->Data != 0)
			{
				WLAN_RADIO_STATUS Status;
				RadioOff		RadioOffData;

				//Radio on : 0, Radio off : 1
				sme_get_radio_mode(pcore_data, &RadioOffData);
				Status.HWStatus = RadioOffData.boHwRadioOff;	//first cut is always on
				Status.SWStatus = RadioOffData.boSwRadioOff;
				(*p->RadioChangeHandler)(p->Data, &Status, sizeof(Status));
			}

		}
		else
			*pBytesNeed = sizeof(WLAN_RADIO_NOTIFICATION);
		break;

    /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    case OID_802_11_CUST_IBSS_FREQUENCY:

		if( InformationBufferLength >= sizeof(ULONG) )
		{
            ULONG   frequency;
			ChanInfo chan;

            frequency = *(ULONG *) InformationBuffer;
			if (frequency > 3000)
				chan.band = BAND_TYPE_OFDM_5;
			else
				chan.band = BAND_TYPE_OFDM_24;
			FreqToChannelNum(chan.band, &chan.ChanNo, frequency);
			sme_set_IBSS_chan(Adapter, chan);
			#ifdef _PE_STATE_DUMP_
			WBDEBUG(("[Set IBSS_FREQUENCY OID] frequency = %d\n", frequency));
			#endif
		}
		else
			*pBytesNeed = sizeof(ULONG);
		break;

	/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	default:
			StatusToReturn = WB_NDIS_STATUS_NOT_SUPPORTED;
	}

	return StatusToReturn;
}
//=============================== NDIS 5.1 OID Set stop ===================================
//Convert band(definition of driver) to network type(definition of NDIS)
void NetworkTypeConvert(PNDIS_802_11_NETWORK_TYPE pNetworkType, UCHAR band)
{
	switch (band)
	{
		case BAND_TYPE_DSSS:
			*pNetworkType = Ndis802_11DS;
			break;
		case BAND_TYPE_OFDM_24:
			*pNetworkType = Ndis802_11OFDM24;
			break;
		case BAND_TYPE_OFDM_5:
			*pNetworkType = Ndis802_11OFDM5;
			break;
		default:
			*pNetworkType = Ndis802_11DS;
			break;
	}
}

// channel number -> channel freq.
void ChannelNumToFreq(UCHAR NetworkType, UCHAR ChannelNumber, ULONG *freq)
{
	//freg : MHz
	switch ( NetworkType)
	{
		case Ndis802_11DS:
		case Ndis802_11OFDM24:
			if (ChannelNumber <=13)
				*freq = 2407 + ChannelNumber*5;
		else
				*freq = 2484;
			break;
		case Ndis802_11OFDM5:
			if (ChannelNumber <= 161)
				*freq = 5000 + ChannelNumber*5;
		else
			*freq = 4000 + ChannelNumber*5;
			break;
		default:
			break;
	}
}

// channel freq. -> channel number
void FreqToChannelNum(UCHAR Band, UCHAR *ChannelNumber, ULONG freq)
{
	//freg : MHz
	switch ( Band )
	{
		case BAND_TYPE_DSSS:
		case BAND_TYPE_OFDM_24:
			if (freq < 2484)
				*ChannelNumber = (UCHAR)((freq-2407)/5);
			else
				*ChannelNumber = 14;
			break;
		case BAND_TYPE_OFDM_5:
			if (freq < 4920)
				*ChannelNumber = (UCHAR)((freq-5000)/5);
			else
				*ChannelNumber = (UCHAR)((freq-4000)/5);
			break;
		default:
			break;
	}
}

//Suppose ChNo will not be larger than 1000
USHORT ChanNo2String(UCHAR ChNo, UCHAR * Str)
{
	UCHAR tmp1, tmp2, flag=0, i=0;

	tmp1 = ChNo/100;
	tmp2 = ChNo%100;
	if (tmp1 != 0)
	{
		Str[i++]= 0x30 + tmp1;
		flag = 1;
	}

	tmp1 = tmp2/10;
	tmp2 = tmp2%10;
	if (tmp1 != 0)
	{
		Str[i++]= 0x30 + tmp1;
		flag = 1;
	}
	else if (flag == 1)
		Str[i++] = 0x30;

	if (tmp2 != 0)
		Str[i++] = 0x30 + tmp2;
	else
		Str[i++] = 0x30;
	Str[i++] = ',';
	return (i);
}


//-------------------------------------------------------------------------------
ULONG USA_channel[] = 
{
	2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, // 2.4G
	5180, 5200, 5220, 5240, 5260, 5280, 5300, 5320, 5745, 5765, 5785, 5805, // 5G
	0
};

ULONG Europe_channel[] = 
{
	2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, // 2.4G
	5180, 5200, 5220, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, // 5G
	5600, 5620, 5640, 5660, 5680, 5700,
	0
};

ULONG Spain_channel[] =
{
	2457, 2462, // 2.4G
	0
};

ULONG France_channel[] =
{
	2457, 2462, 2467, 2472, // 2.4G
	0
};

ULONG Japan_channel[] =
{ 
	2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484, // 2.4G
	5040, 5060, 5080, 5170, 5190, 5210, 5230, 4920, 4940, 4960, 4980, // 5G
	0
};

ULONG Israel_channel[] = 
{
	2422, 2427, 2432, 2437, 2442, 2447, 2457, // 2.4G
	0
};
//The above frequency list are not used actually. [20050929]


static region_name_map regions[] = 
{
	{ WLAN_REGION_EUROPE, "Channel 1-13,",	Europe_channel },
	{ WLAN_REGION_JAPAN,  "Channel 1-14,",	Japan_channel },
	{ WLAN_REGION_USA,    "Channel 1-11,",	USA_channel },
	{ WLAN_REGION_FRANCE, "Channel 10-13,",	France_channel },
	{ WLAN_REGION_SPAIN,  "Channel 10-11,",	Spain_channel },
	{ WLAN_REGION_ISRAEL, "Channel 3-9,",	Israel_channel },
	//{ WLAN_REGION_CANADA, "Canada-IC",	USA_channel },
	{ WLAN_REGION_MAX,    0,        0 } // defined as a sentry
};

UCHAR* get_name_of_region(WLAN_REGION_CODE region)
{
	region_name_map *p = regions;
	
	while (p->region != WLAN_REGION_MAX)
	{
		if (p->region == region)
			return p->name;
		++p;
	}

	//ASSERT(!"Unrecognized region code");
	return 0;
}

/*
ULONG* get_channels_of_region(WLAN_REGION_CODE region)
{
	region_name_map *p = regions;
	
	while (p->region != WLAN_REGION_MAX)
	{
		if (p->region == region)
			return p->channels;
		++p;
	}

	//ASSERT(!"Unrecognized region code!");
	return 0;
}
*/
//=====================================================================
VOID DbgPrintfOID51(NDIS_OID Oid, BOOLEAN IsQuery)
{
	#ifdef _PE_OID_DUMP_
	if(IsQuery)
		WBDEBUG((" QUERY:"));
	else
		WBDEBUG((" SET:"));

	//=======================
    // Print information 
    //=======================
    switch (Oid) {

		case OID_GEN_SUPPORTED_LIST:		WBDEBUG(("OID_GEN_SUPPORTED_LIST"));			break;
		case OID_GEN_HARDWARE_STATUS:		WBDEBUG(("OID_GEN_HARDWARE_STATUS"));			break;
		case OID_GEN_MEDIA_SUPPORTED:		WBDEBUG(("OID_GEN_MEDIA_SUPPORTED"));			break;
		case OID_GEN_MEDIA_IN_USE:			WBDEBUG(("OID_GEN_MEDIA_IN_USE"));			break;
		case OID_GEN_MAXIMUM_LOOKAHEAD:		WBDEBUG(("OID_GEN_MAXIMUM_LOOKAHEAD"));		break;
		case OID_GEN_MAXIMUM_FRAME_SIZE:	WBDEBUG(("OID_GEN_MAXIMUM_FRAME_SIZE"));		break;
		case OID_GEN_MAXIMUM_TOTAL_SIZE:	WBDEBUG(("OID_GEN_MAXIMUM_TOTAL_SIZE"));		break;
		case OID_GEN_MAC_OPTIONS:			WBDEBUG(("OID_GEN_MAC_OPTIONS"));				break;
		case OID_GEN_MEDIA_CONNECT_STATUS:	WBDEBUG(("OID_GEN_MEDIA_CONNECT_STATUS"));	break;
		case OID_GEN_MAXIMUM_SEND_PACKETS:	WBDEBUG(("OID_GEN_MAXIMUM_SEND_PACKETS"));	break;
		case OID_GEN_VENDOR_DRIVER_VERSION:	WBDEBUG(("OID_GEN_VENDOR_DRIVER_VERSION"));	break;
		case OID_GEN_PROTOCOL_OPTIONS:		WBDEBUG(("OID_GEN_PROTOCOL_OPTIONS"));		break;
		//case OID_GEN_LINK_SPEED:			WBDEBUG(("OID_GEN_LINK_SPEED"));				break;
		case OID_GEN_TRANSMIT_BUFFER_SPACE:	WBDEBUG(("OID_GEN_TRANSMIT_BUFFER_SPACE"));	break;
		case OID_GEN_RECEIVE_BUFFER_SPACE:	WBDEBUG(("OID_GEN_RECEIVE_BUFFER_SPACE"));	break;
		case OID_GEN_TRANSMIT_BLOCK_SIZE:	WBDEBUG(("OID_GEN_TRANSMIT_BLOCK_SIZE"));		break;
		case OID_GEN_RECEIVE_BLOCK_SIZE:	WBDEBUG(("OID_GEN_RECEIVE_BLOCK_SIZE"));		break;
		case OID_GEN_VENDOR_DESCRIPTION:	WBDEBUG(("OID_GEN_VENDOR_DESCRIPTION"));		break;
		case OID_GEN_VENDOR_ID:				WBDEBUG(("OID_GEN_VENDOR_ID"));				break;
		case OID_GEN_DRIVER_VERSION:		WBDEBUG(("OID_GEN_DRIVER_VERSION"));			break;
		case OID_GEN_CURRENT_PACKET_FILTER:	WBDEBUG(("OID_GEN_CURRENT_PACKET_FILTER"));	break;
		case OID_GEN_CURRENT_LOOKAHEAD:		WBDEBUG(("OID_GEN_CURRENT_LOOKAHEAD"));		break;
		//case OID_GEN_XMIT_OK:				WBDEBUG(("OID_GEN_XMIT_OK"));					break;
		//case OID_GEN_RCV_OK:				WBDEBUG(("OID_GEN_RCV_OK"));					break;
		//case OID_GEN_XMIT_ERROR:			WBDEBUG(("OID_GEN_XMIT_ERROR"));				break;
		//case OID_GEN_RCV_ERROR:				WBDEBUG(("OID_GEN_RCV_ERROR"));				break;
		case OID_GEN_RCV_NO_BUFFER:			WBDEBUG(("OID_GEN_RCV_NO_BUFFER"));			break;
		case OID_802_3_PERMANENT_ADDRESS:	WBDEBUG(("OID_802_3_PERMANENT_ADDRESS"));		break;
		case OID_802_3_CURRENT_ADDRESS:		WBDEBUG(("OID_802_3_CURRENT_ADDRESS"));		break;
		case OID_802_3_MULTICAST_LIST:		WBDEBUG(("OID_802_3_MULTICAST_LIST"));		break;
		case OID_802_3_MAXIMUM_LIST_SIZE:	WBDEBUG(("OID_802_3_MAXIMUM_LIST_SIZE"));		break;
		case OID_802_3_XMIT_ONE_COLLISION:	WBDEBUG(("OID_802_3_XMIT_ONE_COLLISION"));	break;
		case OID_802_3_XMIT_MORE_COLLISIONS:WBDEBUG(("OID_802_3_XMIT_MORE_COLLISIONS"));	break;
		case OID_PNP_CAPABILITIES:			WBDEBUG(("OID_PNP_CAPABILITIES"));			break;
		case OID_PNP_ENABLE_WAKE_UP:		WBDEBUG(("OID_PNP_ENABLE_WAKE_UP"));			break;
		case OID_PNP_QUERY_POWER:			WBDEBUG(("OID_PNP_QUERY_POWER"));				break;
		case OID_PNP_ADD_WAKE_UP_PATTERN:	WBDEBUG(("OID_PNP_ADD_WAKE_UP_PATTERN"));		break;
		case OID_PNP_REMOVE_WAKE_UP_PATTERN:WBDEBUG(("OID_PNP_REMOVE_WAKE_UP_PATTERN"));	break;
		case OID_PNP_SET_POWER:				WBDEBUG(("OID_PNP_SET_POWER"));				break;
		case OID_GEN_PHYSICAL_MEDIUM:		WBDEBUG(("OID_GEN_PHYSICAL_MEDIUM"));			break;
		case OID_802_11_BSSID:				WBDEBUG(("OID_802_11_BSSID"));					break;
		case OID_802_11_SSID:				WBDEBUG(("OID_802_11_SSID"));					break;
		case OID_802_11_NETWORK_TYPES_SUPPORTED:WBDEBUG(("OID_802_11_NETWORK_TYPES_SUPPORTED"));	break;
		case OID_802_11_NETWORK_TYPE_IN_USE:WBDEBUG(("OID_802_11_NETWORK_TYPE_IN_USE"));	break;
		//case OID_802_11_RSSI:				WBDEBUG(("OID_802_11_RSSI"));					break;
		case OID_802_11_INFRASTRUCTURE_MODE:WBDEBUG(("OID_802_11_INFRASTRUCTURE_MODE"));	break;
		case OID_802_11_FRAGMENTATION_THRESHOLD:WBDEBUG(("OID_802_11_FRAGMENTATION_THRESHOLD"));	break;
		case OID_802_11_RTS_THRESHOLD:		WBDEBUG(("OID_802_11_RTS_THRESHOLD"));			break;
		case OID_802_11_SUPPORTED_RATES:	WBDEBUG(("OID_802_11_SUPPORTED_RATES"));		break;
		case OID_802_11_CONFIGURATION:		WBDEBUG(("OID_802_11_CONFIGURATION"));			break;
		case OID_802_11_ADD_WEP:			WBDEBUG(("OID_802_11_ADD_WEP"));				break;
		case OID_802_11_REMOVE_WEP:			WBDEBUG(("OID_802_11_REMOVE_WEP"));				break;
		case OID_802_11_DISASSOCIATE:		WBDEBUG(("OID_802_11_DISASSOCIATE"));			break;
		case OID_802_11_BSSID_LIST:			WBDEBUG(("OID_802_11_BSSID_LIST"));				break;
		case OID_802_11_AUTHENTICATION_MODE:WBDEBUG(("OID_802_11_AUTHENTICATION_MODE"));	break;
		case OID_802_11_BSSID_LIST_SCAN:	WBDEBUG(("OID_802_11_BSSID_LIST_SCAN"));		break;
		//case OID_802_11_WEP_STATUS:			WBDEBUG(("OID_802_11_WEP_STATUS"));				break;
		case OID_802_11_ENCRYPTION_STATUS:			WBDEBUG(("OID_802_11_ENCRYPTION_STATUS"));				break;
		case OID_802_11_RELOAD_DEFAULTS:	WBDEBUG(("OID_802_11_RELOAD_DEFAULTS"));		break;
		case OID_802_11_ADD_KEY:			WBDEBUG(("OID_802_11_ADD_KEY"));				break;
		case OID_802_11_REMOVE_KEY:			WBDEBUG(("OID_802_11_REMOVE_KEY"));				break;
		case OID_802_11_ASSOCIATION_INFORMATION:	WBDEBUG(("OID_802_11_ASSOCIATION_INFORMATION"));	break;
		case OID_802_11_TEST:				WBDEBUG(("OID_802_11_TEST"));					break;
		default:
			//WBDEBUG(("UNKNOWN"));
			break;
    }
	#endif
}

//from pd50(0209)
void vNetAuthEventInd(PWB32_ADAPTER Adapter, UCHAR *bssid, ULONG flag)
{
    struct event_t
    {
        NDIS_802_11_STATUS_INDICATION       indication;
        NDIS_802_11_AUTHENTICATION_REQUEST  request;
    } event;
	UCHAR		NdisFlag;
 
	if( flag == AUTH_REQUEST_PAIRWISE_ERROR )
		NdisFlag = NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR;
	else
		NdisFlag = NDIS_802_11_AUTH_REQUEST_GROUP_ERROR;

	#ifdef _PE_RX_DUMP_
	WBDEBUG(("!!!!!WPA countermeasure: Auth event\n"));
	#endif
    event.indication.StatusType = Ndis802_11StatusType_Authentication;
    event.request.Length = sizeof(NDIS_802_11_AUTHENTICATION_REQUEST);
    OS_MEMORY_COPY( event.request.Bssid, bssid, 6 );
    event.request.Flags = NdisFlag; 
    NdisMIndicateStatus(Adapter->WbNdis.MiniportAdapterHandle,
                        NDIS_STATUS_MEDIA_SPECIFIC_INDICATION,
                        &event,
                        sizeof(NDIS_802_11_STATUS_INDICATION) + sizeof(NDIS_802_11_AUTHENTICATION_REQUEST));
    NdisMIndicateStatusComplete(Adapter->WbNdis.MiniportAdapterHandle);
}

//TODO : WPA2
///////////////////////////////////////////////////////////////////////////////////////////////
//pre authentication request to OS 
#ifdef _WPA2_
void vPmkIdStatusEvent(PWB32_ADAPTER Adapter) //added by ws 05/04/04
{
    int i,j=0;
	struct status_event{
		                 NDIS_802_11_STATUS_INDICATION       indication; 
				         NDIS_802_11_PMKID_CANDIDATE_LIST      candidatelist;
	} *p;
	char temp_status_event[sizeof(NDIS_802_11_STATUS_INDICATION)+sizeof(NDIS_802_11_PMKID_CANDIDATE_LIST)+sizeof(PMKID_CANDIDATE)*MAX_PMKID_CandidateList];
	PPMKID_CANDIDATE pmkid_candidate;
	p=(struct status_event *)temp_status_event;
	pmkid_candidate=p->candidatelist.CandidateList;
	p->indication.StatusType=Ndis802_11StatusType_PMKID_CandidateList;
	p->candidatelist.Version=1;
    
	for(i=1;i<MAX_BSS_DESCRIPT_ELEMENT;i++)
	{
       if(psBSS(i)->wState >=IDLE_SCAN && boCmpSSID(&psBSS(i)->SSID,&psSME->sDesiredSSID))
	   {
            OS_MEMORY_COPY( pmkid_candidate->BSSID, psBSS(i)->abBssID, 6 );
            if(psBSS(i)->pre_auth)
			   pmkid_candidate->Flags=NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
            else
               pmkid_candidate->Flags=0x0; 
			pmkid_candidate ++;
			j++;
            if(j>MAX_PMKID_Accunt)
                break;
		}
	}
    p->candidatelist.NumCandidates=(ULONG)j;
	NdisMIndicateStatus(
        Adapter->WbNdis.MiniportAdapterHandle,NDIS_STATUS_MEDIA_SPECIFIC_INDICATION,
		&temp_status_event,
		sizeof(NDIS_802_11_STATUS_INDICATION)+
		sizeof(NDIS_802_11_PMKID_CANDIDATE_LIST)+
		sizeof(PMKID_CANDIDATE)*j);
    
	NdisMIndicateStatusComplete(Adapter->WbNdis.MiniportAdapterHandle);

}
#endif //end def _WPA2_



